home *** CD-ROM | disk | FTP | other *** search
/ Ray Dream Studio 5 / Ray Dream.iso / pc / DreamSDK / Windows / SAMPLES / LIGHT / LITE / COMLITE.CPP next >
Encoding:
C/C++ Source or Header  |  1997-07-11  |  12.7 KB  |  349 lines

  1. // Copyright (c)1995 Ray Dream, Inc. All Rights Reserved.
  2. /* $Id: COMLite.cpp 1.5 1997/04/10 00:49:12 damien Exp $ */
  3.  
  4. ////////////////////////////////////////////////////////////////////////
  5. //   First Light Source Example : Beams Light                         //
  6. //--------------------------------------------------------------------//
  7. //   Implementation of the Beams Light Interface                      //
  8. ////////////////////////////////////////////////////////////////////////
  9.  
  10. #include "math.h"
  11.  
  12. #ifndef __COMLITE__
  13. #include "COMLITE.h"
  14. #endif
  15.  
  16. #ifndef __LITEDLL__
  17. #include "LITEDLL.h"
  18. #endif
  19.  
  20. #ifndef __3DCOFAIL__
  21. #include "3DCoFail.h"
  22. #endif
  23.  
  24. // Tool to get the Global Coordinates from the Local Coordinates 
  25. void LocalToGlobal(TRANSFORM3D* transform,VECTOR3D* LocalPos,VECTOR3D* GlobalPos) {
  26.   // Axes rotations
  27.   (*GlobalPos)[0]=transform->fR.fix*(*LocalPos)[0]
  28.                   +transform->fR.fjx*(*LocalPos)[1]
  29.                   +transform->fR.fkx*(*LocalPos)[2];
  30.   (*GlobalPos)[1]=transform->fR.fiy*(*LocalPos)[0]
  31.                   +transform->fR.fjy*(*LocalPos)[1]
  32.                   +transform->fR.fjy*(*LocalPos)[2];
  33.   (*GlobalPos)[2]=transform->fR.fiz*(*LocalPos)[0]
  34.                   +transform->fR.fjz*(*LocalPos)[1]
  35.                   +transform->fR.fkz*(*LocalPos)[2];
  36.   // Unit conversion : Points Units to 3D Units 
  37.   (*GlobalPos)[0] /= 288.0;  
  38.   (*GlobalPos)[1] /= 288.0;  
  39.   (*GlobalPos)[2] /= 288.0;  
  40.   // Origin translation
  41.   (*GlobalPos)[0] += transform->fT[0];
  42.   (*GlobalPos)[1] += transform->fT[1];
  43.   (*GlobalPos)[2] += transform->fT[2];
  44.   }
  45.  
  46. // Tool to get the Global Coordinates from the Local Coordinates for a Vector
  47. void LocalToGlobalVector(TRANSFORM3D* transform,VECTOR3D* LocalPos,VECTOR3D* GlobalPos) {
  48.   // Axes rotations
  49.   (*GlobalPos)[0]=transform->fR.fix*(*LocalPos)[0]
  50.                   +transform->fR.fjx*(*LocalPos)[1]
  51.                   +transform->fR.fkx*(*LocalPos)[2];
  52.   (*GlobalPos)[1]=transform->fR.fiy*(*LocalPos)[0]
  53.                   +transform->fR.fjy*(*LocalPos)[1]
  54.                   +transform->fR.fky*(*LocalPos)[2];
  55.   (*GlobalPos)[2]=transform->fR.fiz*(*LocalPos)[0]
  56.                   +transform->fR.fjz*(*LocalPos)[1]
  57.                   +transform->fR.fkz*(*LocalPos)[2];
  58.   }
  59.  
  60. // Tool to get the Local Coordinates from the Global Coordinates             
  61. void GlobalToLocal(TRANSFORM3D* transform,VECTOR3D* GlobalPos,VECTOR3D* LocalPos) {
  62.   // Origin translation
  63.   (*GlobalPos)[0] -= transform->fT[0];
  64.   (*GlobalPos)[1] -= transform->fT[1];
  65.   (*GlobalPos)[2] -= transform->fT[2];
  66.    // Unit conversion : 3D Units to Points Units
  67.   (*GlobalPos)[0] *= 288.0;
  68.   (*GlobalPos)[1] *= 288.0;
  69.   (*GlobalPos)[2] *= 288.0;
  70.  
  71.   // Axes rotations
  72.   (*LocalPos)[0]=transform->fR.fix*(*GlobalPos)[0]
  73.                   +transform->fR.fiy*(*GlobalPos)[1]
  74.                   +transform->fR.fiz*(*GlobalPos)[2];
  75.   (*LocalPos)[1]=transform->fR.fjx*(*GlobalPos)[0]
  76.                   +transform->fR.fjy*(*GlobalPos)[1]
  77.                   +transform->fR.fjz*(*GlobalPos)[2];
  78.   (*LocalPos)[2]=transform->fR.fkx*(*GlobalPos)[0]
  79.                   +transform->fR.fky*(*GlobalPos)[1]
  80.                   +transform->fR.fkz*(*GlobalPos)[2];
  81.   }
  82.  
  83. // Tool to get the Local Coordinates from the Global Coordinates for a Vector
  84. void GlobalToLocalVector(TRANSFORM3D* transform,VECTOR3D* GlobalPos,VECTOR3D* LocalPos) {
  85.  
  86.   // Axes rotations
  87.   (*LocalPos)[0]=transform->fR.fix*(*GlobalPos)[0]
  88.                   +transform->fR.fiy*(*GlobalPos)[1]
  89.                   +transform->fR.fiz*(*GlobalPos)[2];
  90.   (*LocalPos)[1]=transform->fR.fjx*(*GlobalPos)[0]
  91.                   +transform->fR.fjy*(*GlobalPos)[1]
  92.                   +transform->fR.fjz*(*GlobalPos)[2];
  93.   (*LocalPos)[2]=transform->fR.fkx*(*GlobalPos)[0]
  94.                   +transform->fR.fky*(*GlobalPos)[1]
  95.                   +transform->fR.fkz*(*GlobalPos)[2];
  96.   }
  97.  
  98.  
  99.  
  100.  
  101.  
  102. // Constructor / Destructor of the C++ Object :
  103. BeamsLight::BeamsLight() {
  104.   fCRef=0;  // Reference counter
  105.   // Rotation Matrix initialized to identity :
  106.   fTransform.fR.fix=fTransform.fR.fjy=fTransform.fR.fkz=1.0;
  107.   fTransform.fR.fjx=fTransform.fR.fkx=0.0;
  108.   fTransform.fR.fiy=fTransform.fR.fky=0.0;
  109.   fTransform.fR.fiz=fTransform.fR.fjz=0.0;
  110.   // Translation Vector initialized to zero  :
  111.   fTransform.fT[0]=fTransform.fT[1]=fTransform.fT[2]=0.0;
  112.   // Data initialization :
  113.   // -- Default color : White
  114.   fData.fLightColor.Mode=0; // RGB Color
  115.   fData.fLightColor.R=1.0;
  116.   fData.fLightColor.G=1.0;
  117.   fData.fLightColor.B=1.0;
  118.   fData.fLightColor.A=0.0;
  119.   // -- Aperture Angles
  120.   fData.fHorApertureAngle=90;     // 90∞ (-45∞ to 45∞)
  121.   fData.fVerApertureAngle=90;     // 
  122.   fData.fBeamAperture=5;          // 5∞ for each beam
  123.   // -- Intensity of the Beams
  124.   fData.fIntensity=1.0;  // 100% of intensity
  125.   // -- Numbers of Beams
  126.   fData.fNbBeamsHorizontally=10;
  127.   fData.fNbBeamsVertically=10;
  128.     ExtensionDataChanged();  // Preprocessed values
  129.   }
  130.   
  131. BeamsLight::~BeamsLight() {
  132.   global_count_Obj--; 
  133.   }
  134.   
  135. // IUnknown Interface :
  136. HRESULT BeamsLight::QueryInterface(THIS_ REFIID riid,LPVOID* ppvObj) {
  137.   *ppvObj=NULL;
  138.   
  139.   // The BeamsLight knows the interfaces of the parent Objects
  140.   if (IsEqualIID(riid, IID_IUnknown))
  141.     *ppvObj=(LPVOID)this;
  142.   else if (IsEqualIID(riid, IID_I3DExLightsource))
  143.     *ppvObj=(LPVOID)this;
  144.   else if (IsEqualIID(riid, IID_I3DExDataExchanger))
  145.     *ppvObj=(LPVOID)this;
  146.   else if (IsEqualIID(riid, IID_I3DExtension))
  147.     *ppvObj=(LPVOID)this;
  148.     
  149.   // we must add reference if we return an interface
  150.   if (*ppvObj!=NULL) {
  151.     ((LPUNKNOWN)*ppvObj)->AddRef();
  152.     return NOERROR;
  153.     }
  154.   else {
  155.     return ResultFromScode(E_NOINTERFACE);
  156.     }
  157.   }
  158.  
  159. ULONG BeamsLight::AddRef(THIS) {
  160.   return fCRef++;
  161.   }
  162.   
  163. ULONG BeamsLight::Release(THIS) {
  164.   ULONG UnreleaseObject=fCRef--;
  165.   
  166.   if (fCRef==0)
  167.      delete this; // No reference left so delete the object
  168.   
  169.   return UnreleaseObject;
  170.    // Use local variable because if the object is destructed
  171.    // fCRef do not exist
  172.   }
  173.   
  174. // I3DExtension methods :
  175. I3DExtension* BeamsLight::Clone(THIS) {
  176.   BeamsLight* theClone = new BeamsLight;
  177.   if (theClone) {
  178.     theClone->AddRef();
  179.     theClone->fTransform=fTransform; // Copy all the Data
  180.     theClone->fData     =fData;
  181.     theClone->fVerAng   =fVerAng;
  182.     theClone->fHorAng   =fHorAng;
  183.     theClone->fBeamLimit=fBeamLimit;
  184.     theClone->fBeamAngle=fBeamAngle;
  185.     }                               
  186.   return theClone;
  187.   }   
  188.         
  189. HRESULT BeamsLight::ShellUtilitiesInit(THIS_ IShUtilities* shellUtilities) {
  190.   InitCoFailure(shellUtilities);
  191.   return NOERROR;
  192.   }
  193.         
  194. // I3DExDataExchanger methods :
  195. ExtensionDataMap* BeamsLight::GetExtensionDataMap(THIS) {
  196.   return NULL;
  197.   }               
  198.   
  199. void* BeamsLight::GetExtensionDataBuffer(THIS) {
  200.   return &fData; // The Shell uses this pointer to set the values of the camera's parameters
  201.   }
  202.   
  203. HRESULT BeamsLight::ExtensionDataChanged(THIS) {
  204.   fHorAng=((NUM3D)fData.fHorApertureAngle)/2.0; // Recalculate Aperture Angles
  205.   fVerAng=((NUM3D)fData.fVerApertureAngle)/2.0;
  206.   fBeamAngle=((NUM3D)fData.fBeamAperture)/2.0;
  207.     fBeamLimit=cos(fBeamAngle/180.0*3.14159265358979323846); //QuickSinCos(fBeamAngle,sinus,cosinus);
  208.   return NOERROR;
  209.   }
  210.  
  211. // This function is here, to allow you to create and use special resource.
  212. HRESULT BeamsLight::HandleEvent(THIS_ ULONG SourceID) {
  213.   return ResultFromScode(E_NOTIMPL);
  214.   }
  215.  
  216. short BeamsLight::GetResID(THIS) {
  217.   return 132; // This is the view ID in the resource file
  218.   }
  219.   
  220. // I3DExLightsource methods :
  221. // set the coordinates Transformation values
  222. HRESULT BeamsLight::SetTransform(THIS_ TRANSFORM3D* transform) {
  223.   fTransform=*transform;
  224.   return ResultFromScode(S_OK);
  225.   }
  226.  
  227. HRESULT BeamsLight::GetDirection(THIS_ VECTOR3D* position, VECTOR3D* resultDirection, NUM3D* resultDistance) {
  228.   (*resultDirection)[0]=fTransform.fT[0]-(*position)[0];
  229.   (*resultDirection)[1]=fTransform.fT[1]-(*position)[1];
  230.   (*resultDirection)[2]=fTransform.fT[2]-(*position)[2]; // Vector from surface point to the BeamsLight
  231.     *resultDistance=sqrt(SQR((*resultDirection)[0]) + SQR((*resultDirection)[1]) + SQR((*resultDirection)[2]));
  232.     (*resultDirection)[0] /= *resultDistance;
  233.     (*resultDirection)[1] /= *resultDistance;
  234.     (*resultDirection)[2] /= *resultDistance;
  235.   //*resultDistance=resultDirection->GetNorm(); // Distance from the point to the light
  236.   //*resultDirection/=(*resultDistance);          // Normalized vector
  237.   return ResultFromScode(S_OK);
  238.   }
  239.   
  240.   
  241. BOOLEAN BeamsLight::GetColor(THIS_ VECTOR3D* position, VECTOR3D* direction, NUM3D distance, COLOR3D* result, BOOLEAN* callForShadowEffect) {
  242.   VECTOR3D localVector,refDir;
  243.   NUM3D    angle,nearest_dir,hor,ver,theta,phi,r;
  244.   NUM3D    costheta,sintheta,cosphi,sinphi;
  245.   NUM3D    cosdifferentialAngle; 
  246.   NUM3D    angleLimit=360.0;
  247.  
  248.   *callForShadowEffect=TRUE; // We always want shadows for this lightsource
  249.  
  250.   GlobalToLocalVector(&fTransform,direction,&localVector);
  251.   
  252.   // initialize result to default color (intensity included)
  253.   *result=fData.fLightColor;
  254.   result->R*=fData.fIntensity;
  255.   result->G*=fData.fIntensity;
  256.   result->B*=fData.fIntensity;             
  257.   
  258.   // Nearest direction vector determination  
  259.   
  260.   if (fData.fNbBeamsHorizontally!=1) {
  261.     // direction is calculated in the Spherical Coordinates (see Spheric Camera)
  262.     // -- Horizontal Determination
  263.     angle=atan2(localVector[0],localVector[2])*180.0/3.14159265358979323846; //QuickArcSinCos(localVector[0],localVector[2],angle);
  264.     if (angle>angleLimit/2.0) {
  265.       angle-=angleLimit; 
  266.       }
  267.     if ((angle>fHorAng+fBeamAngle)||(angle<-fHorAng-fBeamAngle)) return FALSE; // the point is outside the maximum horizontal aperture
  268.  
  269.     nearest_dir=(angle/(fHorAng*2.0)+0.5)*((NUM3D)fData.fNbBeamsHorizontally-1.0);
  270.     hor=floor(nearest_dir);
  271.     if (nearest_dir-hor>0.5) hor+=1.0;
  272.     if (hor>((NUM3D)fData.fNbBeamsHorizontally-1.0)) hor=((NUM3D)fData.fNbBeamsHorizontally-1.0);
  273.     if (hor<0.0) hor=0.0;
  274.     // hor must be between 0 and fNbBeamsHorizontally-1
  275.     theta=fHorAng*2.0*(hor/((NUM3D)fData.fNbBeamsHorizontally-1)-0.5);
  276.     }
  277.   else {
  278.     theta=0.0;
  279.     }
  280.   if (fData.fNbBeamsVertically!=1) {
  281.     // -- Vertical Determination
  282.     r=localVector[0]*localVector[0]+localVector[2]*localVector[2];
  283.     r=sqrt(r);
  284.     angle=atan2(localVector[1],r)*180.0/3.14159265358979323846; //QuickArcSinCos(localVector[1],r,angle);
  285.     if (angle>(angleLimit/2.0)) {
  286.       angle-=angleLimit;
  287.       }
  288.     if ((angle>fVerAng+fBeamAngle)||(angle<-fVerAng-fBeamAngle)) return FALSE; // the point is outside the maximum vertical aperture
  289.     nearest_dir=(angle/(fVerAng*2.0)+0.5)*((NUM3D)fData.fNbBeamsVertically-1.0);
  290.     ver=floor(nearest_dir);
  291.     if (nearest_dir-ver>0.5) ver+=1.0;
  292.     if (ver>((NUM3D)fData.fNbBeamsVertically-1.0)) ver=((NUM3D)fData.fNbBeamsVertically-1.0);
  293.     if (ver<0.0) ver=0.0;
  294.     // ver must be between 0 and fNbBeamsVertically-1
  295.     phi=(fVerAng*2.0)*(ver/((NUM3D)fData.fNbBeamsVertically-1.0)-0.5);
  296.     }
  297.   else {
  298.     phi=0.0;
  299.     }
  300.   // nearest direction vector
  301.   
  302.   // Spherical Coordinates of the direction vector
  303.   sintheta=sin(theta/180.0*3.14159265358979323846);
  304.     costheta=cos(theta/180.0*3.14159265358979323846); //QuickSinCos(theta,sintheta,costheta);
  305.   sinphi=sin(phi/180.0*3.14159265358979323846);
  306.     cosphi=cos(phi/180.0*3.14159265358979323846); //QuickSinCos(phi,sinphi,cosphi);
  307.   refDir[0]=sintheta*cosphi;
  308.   refDir[1]=sinphi;
  309.   refDir[2]=costheta*cosphi;
  310.   // Direction comparaison
  311.   cosdifferentialAngle=refDir[0]*localVector[0] +     // dot product to get the cosinus of the angle
  312.                            refDir[1]*localVector[1] +
  313.                                              refDir[2]*localVector[2];
  314.   if (cosdifferentialAngle<fBeamLimit) return FALSE; // the point is outside the Beam
  315.   return TRUE;  
  316.   }
  317.                         
  318. // can the light source be visible in the 3D perspective display
  319. BOOLEAN BeamsLight::IsVisibleInPerspective(THIS) {
  320.   return TRUE; // the source is not a distant light (like the sun)
  321.                // so it can be in the 3D perspective display.
  322.   }
  323.                           
  324. // the BeamsLight gives a perfect shadow effect (no light behind an object)                          
  325. HRESULT BeamsLight::ShadowEffect(THIS_ NUM3D distance, COLOR3D* result) {
  326.   result->R=0.0;
  327.   result->G=0.0;
  328.   result->B=0.0;
  329.   return ResultFromScode(S_OK);
  330.   }
  331.  
  332.  
  333. LightTraceElement* BeamsLight::GetNewTrace(THIS_ short* nb)    {
  334.     return NULL;
  335.     }
  336.  
  337. ULONG BeamsLight::GetPrimitiveID(THIS)    {
  338.     return 0;
  339.     }
  340.   
  341. HRESULT BeamsLight::ForEachShadowBuffer(THIS_ ForEachShadowBufferCallback proc, void* priv) {
  342.     /*** to do ***/
  343.     return ResultFromScode(E_NOTIMPL);
  344.     }
  345.  
  346. HRESULT BeamsLight::GetLightParameter(THIS_ long keyword, void* parameter) {
  347.     return ResultFromScode(E_NOTIMPL);
  348.     }
  349.